package com.jcommander.gui;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;

import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;

import com.jcommander.JCommander;
import com.jcommander.gui.layouts.ButtonAtRightFlowLayout;
import com.jcommander.gui.layouts.FallItemFlowLayout;
import com.jcommander.gui.locale.ResourceBundler;
import com.jcommander.utils.ImageLoader;

public class GUIBuilder {

	private final SidePaneBuilder leftSidePane;
	private final SidePaneBuilder rightSidePane;
	private SidePaneBuilder currentSidePane;
	private final FButtonAction fButtonAction = new FButtonAction();
	
	public GUIBuilder() {
		
		leftSidePane = new SidePaneBuilder(new FocusListener() {
			
			public void focusLost(FocusEvent arg0) {
				leftSidePane.clearSelection();
			}
			public void focusGained(FocusEvent arg0) {
				currentSidePane = leftSidePane;
			}
		});
		
		rightSidePane = new SidePaneBuilder(new FocusListener() {
			
			public void focusLost(FocusEvent e) {
				rightSidePane.clearSelection();
			}
			
			public void focusGained(FocusEvent e) {
				currentSidePane = rightSidePane;
			}
		});
		leftSidePane.setFriendManager(rightSidePane.getFileSystemManager());
		rightSidePane.setFriendManager(leftSidePane.getFileSystemManager());
		
	}
	
	public JPanel createMainPanel() {
		JPanel mainPanel = new JPanel(new BorderLayout());
		mainPanel.add(createTopPanel(), BorderLayout.NORTH);
		mainPanel.add(createCenterPanel(), BorderLayout.CENTER);
		mainPanel.add(createBottomPanel(), BorderLayout.SOUTH);
		
		mainPanel.setOpaque(true);
		return mainPanel;
		
	}
	
	private Box createTopPanel() {
		Box box = Box.createVerticalBox();
		box.add(createMenuBar());
		box.add(createTopToolBar());
		return box;
	}
	
	private JMenuBar createMenuBar() {
		JMenuBar menuBar = new JMenuBar();
		menuBar.setLayout(new ButtonAtRightFlowLayout(FlowLayout.LEFT, menuBar.getHeight()));
		
		JMenu fileMenu = new JMenu();
		JMenu markMenu = new JMenu();
		JMenu commandsMenu = new JMenu();
		JMenu netMenu = new JMenu();
		JMenu showMenu = new JMenu();
		JMenu confMenu = new JMenu();
		JMenu startMenu = new JMenu();
		JMenu helpMenu = new JMenu();
		
		fileMenu.add(new JMenuItem("Empty items"));
		markMenu.add(new JMenuItem("Empty items"));
		commandsMenu.add(new JMenuItem("Empty items"));
		netMenu.add(new JMenuItem("Empty items"));
		showMenu.add(new JMenuItem("Empty items"));
		confMenu.add(new JMenuItem("Empty items"));
		startMenu.add(new JMenuItem("Empty items"));
		helpMenu.add(new JMenuItem("Empty items"));
		
		menuBar.add(fileMenu);
		menuBar.add(markMenu);
		menuBar.add(commandsMenu);
		menuBar.add(netMenu);
		menuBar.add(showMenu);
		menuBar.add(confMenu);
		menuBar.add(startMenu);
		menuBar.add(helpMenu);
		
		ResourceBundler.getInstance().addJMenu("fileMenu", fileMenu);
		ResourceBundler.getInstance().addJMenu("markMenu", markMenu);
		ResourceBundler.getInstance().addJMenu("commandsMenu", commandsMenu);
		ResourceBundler.getInstance().addJMenu("netMenu", netMenu);
		ResourceBundler.getInstance().addJMenu("showMenu", showMenu);
		ResourceBundler.getInstance().addJMenu("confMenu", confMenu);
		ResourceBundler.getInstance().addJMenu("startMenu", startMenu);
		ResourceBundler.getInstance().addJMenu("helpMenu", helpMenu);
		return menuBar;
	}
	
	private JToolBar createTopToolBar() {
		JToolBar toolBar = new JToolBar();
		
		toolBar.setLayout(new FallItemFlowLayout(FlowLayout.LEFT, toolBar.getHeight()));
		
		toolBar.setFloatable(false);
		JButton plButton = new JButton(ImageLoader.getInstance().loadImage("/images/pl_flag.png"));
		JButton engButton = new JButton(ImageLoader.getInstance().loadImage("/images/eng_flag.png"));
		plButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				ResourceBundler.getInstance().setLocale(new Locale("PL"));
			}
		});
		engButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				ResourceBundler.getInstance().setLocale(new Locale("EN"));
			}
		});
		
		toolBar.add(plButton);
		toolBar.add(engButton);
		
		return toolBar;
	
	}
	
	private JSplitPane createCenterPanel() {
		JSplitPane splitPaneH = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, 
				leftSidePane.createMainSidePanePanel(), rightSidePane.createMainSidePanePanel());
		splitPaneH.setResizeWeight(0.5);
		return splitPaneH;
	}
	
	private Box createBottomPanel() {
		Box box = Box.createVerticalBox();
		box.add(createSearchPanel());
		box.add(crateFButtonPanel());
		return box;
	}
	
	private Box createSearchPanel() {
		Box searchPanel = Box.createHorizontalBox();
		
		//TODO this should show disk which is set in combobox
		Label searchLabel = new Label("Disk:");
		
		final JComboBox searchComboBox = new JComboBox(new String[]{"first", "second", "third"});
		searchComboBox.setMaximumRowCount(4);
		searchComboBox.setEditable(true);
		AutoCompleteDecorator.decorate(searchComboBox);
		searchComboBox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent actionEvent) {
				String selectedItem = (String)searchComboBox.getSelectedItem();
				boolean contains = false;
				for (int i = 0; i < searchComboBox.getItemCount(); i++) {
					if (searchComboBox.getItemAt(i).equals(selectedItem)) {
						contains = true;
					}
				}
				if (!contains) {
					if (searchComboBox.getItemCount() == searchComboBox.getMaximumRowCount()) {
						searchComboBox.remove(0);
					}
					searchComboBox.addItem(selectedItem);
				}
			}
		});
		JPanel rightPanel = new JPanel(new BorderLayout());
		rightPanel.add(searchLabel, BorderLayout.WEST);
		rightPanel.add(searchComboBox, BorderLayout.CENTER);
		
		Dimension minSize = new Dimension(0, 20);
		Dimension prefSize = new Dimension(200, 20);
		Dimension maxSize = new Dimension(Short.MAX_VALUE, 20);
		searchPanel.add(new Box.Filler(minSize, prefSize, maxSize));
		searchPanel.add(rightPanel);
		
		return searchPanel;
	}	
	
	private JPanel crateFButtonPanel() {
		JPanel fbuttonPanel = new JPanel(new GridLayout(1,7));
		
		Map<Integer, JButton> fButtons = new TreeMap<Integer, JButton>();
		
		JButton viewButton = new JButton("F3 View");
		viewButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F3"), "viewAction");
		viewButton.getActionMap().put("viewAction", fButtonAction.viewAction());
		fButtons.put(3, viewButton);
		ResourceBundler.getInstance().addJButton("viewButton", viewButton);
		
		JButton editButton = new JButton("F4 Edit");
		editButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F4"), "editAction");
		editButton.getActionMap().put("editAction", fButtonAction.editAction());
		fButtons.put(4, editButton);
		ResourceBundler.getInstance().addJButton("editButton", editButton);
		
		JButton copyButton = new JButton("F5 Copy");
		copyButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F5"), "copyAction");
		copyButton.getActionMap().put("copyAction", fButtonAction.copyAction());
		copyButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				fButtonAction.copyAction().actionPerformed(e);
			}
		});
		fButtons.put(5, copyButton);
		ResourceBundler.getInstance().addJButton("copyButton", copyButton);
		
		JButton moveButton = new JButton("F6 Move");
		moveButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F6"), "moveAction");
		moveButton.getActionMap().put("moveAction", fButtonAction.moveAction());
		moveButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				fButtonAction.moveAction().actionPerformed(e);
			}
		});
		fButtons.put(6, moveButton);
		ResourceBundler.getInstance().addJButton("moveButton", moveButton);
		
		JButton newfolderButton = new JButton("F7 NewFolder");
		newfolderButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F7"), "newfolderAction");
		newfolderButton.getActionMap().put("newfolderAction", fButtonAction.newfolderAction());
		newfolderButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				fButtonAction.newfolderAction().actionPerformed(e);
			}
		});
		fButtons.put(7, newfolderButton);
		ResourceBundler.getInstance().addJButton("newfolderButton", newfolderButton);
		
		JButton deleteButton = new JButton("F8 Delete");
		deleteButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F8"), "none"); 
		deleteButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_F8, 0), "deleteAction");
		deleteButton.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "deleteAction");
		deleteButton.getActionMap().put("deleteAction", fButtonAction.deleteAction());
		deleteButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				fButtonAction.deleteAction().actionPerformed(e);
			}
		});
		fButtons.put(8, deleteButton);
		ResourceBundler.getInstance().addJButton("deleteButton", deleteButton);
		
		JButton exitButton = new JButton("Alt+F4 Exit");
		exitButton.setMnemonic(KeyEvent.VK_F4);
		exitButton.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				JCommander.exitApplication();
			}
		});
		fButtons.put(9, exitButton);
		ResourceBundler.getInstance().addJButton("exitButton", exitButton);
		
		for (JButton button : fButtons.values()) {
			fbuttonPanel.add(button);
		}
		
		return fbuttonPanel;
	}
	
	private class FButtonAction {
		
		public Action deleteAction() {
			return new AbstractAction() {

				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent arg0) {
					if (currentSidePane != null) {
						currentSidePane.getFileSystemManager().fireDeleteFile();
					}
				}
			};
		}
		
		public Action newfolderAction() {
			return new AbstractAction() {

				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent arg0) {
					if (currentSidePane != null) {
						currentSidePane.getFileSystemManager().fireCreateNewFolder();
					}
				}
			};
		}
		
		public Action moveAction() {
			return new AbstractAction() {
				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent arg0) {
					if (currentSidePane != null) {
						currentSidePane.getFileSystemManager().fireMoveFile();
					}
				}
			};
		}
		
		public Action copyAction() {
			return new AbstractAction() {
	
				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent arg0) {
					if (currentSidePane != null) {
						currentSidePane.getFileSystemManager().fireCopyFile();
					}
				}
			};
		}
		
		public Action viewAction() {
			return new AbstractAction() {
	
				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent arg0) {
					JOptionPane.showMessageDialog(JCommander.getFrame(), "You pressed VIEW button.", 
							"JCommander", JOptionPane.INFORMATION_MESSAGE);
				}
			};
		}
		
		public Action editAction() {
			return new AbstractAction() {
	
				private static final long serialVersionUID = 1L;

				public void actionPerformed(ActionEvent arg0) {
					JOptionPane.showMessageDialog(JCommander.getFrame(), "You pressed EDIT button.", 
							"JCommander", JOptionPane.INFORMATION_MESSAGE);
				}
			};
		}
	}
	
}